package com.zhny.aiot.bighouse.pull.curtain.plugin;

import com.google.common.collect.ImmutableMap;
import com.zhny.aiot.bighouse.pull.curtain.plugin.model.PullCurtainStoreEntry;
import com.zhny.aiot.plugin.ICenterFacilities;
import com.zhny.aiot.plugin.IDeviceFactory;
import com.zhny.aiot.plugin.core.model.IRequestMessage;
import com.zhny.aiot.plugin.core.utils.MessageUtils;
import com.zhny.aiot.plugin.modbus.ModemEngine;
import com.zhny.aiot.plugin.modbus.device.ModemConfig;
import com.zhny.aiot.plugin.modbus.device.ModemDevice;
import com.zhny.aiot.plugin.modbus.device.modbus.ModbusCommandParam;
import com.zhny.aiot.plugin.modbus.handler.model.ModemRequestMessage;
import com.zhny.aiot.plugin.modbus.handler.model.ModemResponseMessage;
import com.zhny.aiot.plugin.model.DeviceEntity;
import com.zhny.aiot.plugin.model.MessageEntry;
import com.zhny.aiot.plugin.model.MessageType;
import com.zhny.aiot.plugin.model.TaskEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;

public class PullCurtainDevice extends ModemDevice<PullCurtainStoreEntry> {
    private static final Logger logger=LoggerFactory.getLogger (PullCurtainStoreEntry.class);
    private final Map<String, ModbusCommandParam> CommandOperations;

    public PullCurtainDevice(ModemEngine engine, IDeviceFactory<ModemConfig> factory, ICenterFacilities centerFacilities, DeviceEntity entity) {
        super (engine, factory, centerFacilities, entity);

        CommandOperations=new ImmutableMap.Builder<String, ModbusCommandParam> ()
                .put ("open", ModbusCommandParam.valueOf ((short) 6, 10, 0x0065))
                .put ("close", ModbusCommandParam.valueOf ((short) 6, 10, 0x0066))
                .put ("stop", ModbusCommandParam.valueOf ((short) 6, 10, 0x0068))
                .put ("query", ModbusCommandParam.valueOf ((short) 3, 3, 1))
                .build ();
    }

    @Override
    public void onDecoder(ModemResponseMessage modemResponseMessage) {
        MessageEntry entry=MessageUtils.createMessageEntry (this.getId ());
        entry.setType (MessageType.RESULT);
        entry.getProperties ().put ("gprs", ((ModemConfig) this.getConfig ()).getGprsNo ());
        entry.getProperties ().put ("address", ((ModemConfig) this.getConfig ()).getAddress ());

        int isRecord=modemResponseMessage.getData ().readByte ();
        int status=modemResponseMessage.getData ().readByte ();
        String value="";
        if(modemResponseMessage.getFunction () == 0x06) {
            value=onStatusConvert (status);
        }else if(modemResponseMessage.getFunction () == 0x03) {
            value=onQueryConvert (status);
        }else {
            entry.setType (MessageType.ERROR);
            nofity (entry);
        }
        PullCurtainStoreEntry storeEntry=new PullCurtainStoreEntry ();
        logger.info ("拉幕机：{} 获取值:{}", this.getDeviceEntity ().getName (), value);
        storeEntry.setPullCurtainStatus (value);
        entry.setData (storeEntry);
        nofity (entry);
        saveReal (storeEntry);
    }

    private String onQueryConvert(int status) {
        return status == 0 ? "错误" :
                status == 1 ? "全开" :
                        status == 2 ? "全关" :
                                status == 3 ? "半开":"异常";
    }

    private String onStatusConvert(int status) {
        return status == 101 ? "全开" :
                status == 102 ? "全关" :
                        status == 103 ? "学习" :
                                status == 104 ? "停止" : "错误";
    }

    @Override
    protected IRequestMessage getCommand(TaskEntity taskEntity) {
        MessageEntry entry=MessageUtils.createMessageEntry (this.getId ());
        entry.getProperties ().put ("task_name", taskEntity.getMethodName ());
        entry.setType (MessageType.OPERATION);
        ModbusCommandParam command=CommandOperations.get (taskEntity.getMethodName ());
        if(command == null) {
            entry.setType (MessageType.ERROR);
            entry.setData (String.format ("factory[%s] no support command [%s]", getTypeId (), taskEntity.getMethodName ()));
            this.nofity (entry);
            return null;
        }

        return new ModemRequestMessage (
                Integer.valueOf (this.getConfig ().getAddress ()),
                command.getOper (),
                command.getRegAdress (),
                command.getDataSize ()
        );
    }

    @Override
    protected void disposable() {

    }
}
